#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QToolButton>
#include<QPainter>
#include<QDebug>
#include<QVBoxLayout>
#include<QColorDialog>
#include<cmath>
#include<QCheckBox>
#include<QLineEdit>
#include<windows.h>
#include<QPushButton>
#include<QMouseEvent>
#include<QPalette>
#include<QLineF>
using namespace std;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    type = DDA;

    //DDA算法选择按钮
    QToolButton* DDA_button = new QToolButton(this);
    DDA_button->setText("DDA");
    connect(DDA_button,  &QToolButton::clicked, this, [=](){
        type = DDA;
    });
    ui->toolBar_line->addWidget(DDA_button);

    //BRESENHAM 算法选择按钮
    QToolButton* BRESENHAM_button = new QToolButton(this);
    BRESENHAM_button->setText("BRESEMHAM");
    connect(BRESENHAM_button,  &QToolButton::clicked, this, [=](){
        type = BRESENHAM;
    });
    ui->toolBar_line->addWidget(BRESENHAM_button);

    //选择颜色
    QToolButton* color_button = new QToolButton(this);
    color_button->setStyleSheet("background-color: rgb(0, 0, 0)");
    connect(color_button, &QToolButton::clicked, this, [=](){
        QColorDialog dialog;
        QColor color = dialog.getColor(color, this, "选择字体颜色",
                                       QColorDialog::ShowAlphaChannel);
        if(this->now_color != color)
        {
            int r = 0, g = 0, b = 0;
            color.getRgb(&r,&g,&b);
            this->now_color.setRgb(r, g, b);
            color_button->setStyleSheet(QString("background-color: rgb(%1,%2,%3)").arg(r).arg(g).arg(b));
        }
    });
    ui->toolBar_line->addWidget(color_button);

    //清空按钮
    QToolButton* clear_button = new QToolButton(this);
    clear_button->setText("清空");
    connect(clear_button, &QToolButton::clicked, this, [=](){
        points.clear();
        lines.clear();
        update();
    });
    ui->toolBar_line->addWidget(clear_button);

}

MainWindow::~MainWindow()
{
    delete ui;
}

//鼠标按下
void MainWindow::mousePressEvent(QMouseEvent *event)
{
     add_line(event->pos());
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    //设置画笔
    QPainter painter(this);
    QPen pen(QColor(0,0,0));
    QBrush brush(Qt::white);
    painter.setBrush(brush);
    painter.drawRect(QRect(10,45,800,600));
    painter.setPen(pen);

    //绘制网格
    int tempx = 10;
    int tempy = 45;
    for(;tempx<810;tempx+=5)
    {
        painter.drawLine(tempx,45,tempx,645);
    }
    for(;tempy<645;tempy+=5)
    {
        painter.drawLine(10,tempy,810,tempy);
    }

    //画所有的直线
    for(int i=0;i<lines.size();i++)
    {
        QList<QPoint> templine = lines[i].point;

        brush.setColor(lines[i].color);
        painter.setBrush(brush);//用线条的颜色
        for(int j=0;j<templine.size();j++)//一个点一个点生成
        {
            QPoint temppoint = templine[j];
            painter.drawRect(QRect(5*temppoint.x()+10,5*temppoint.y()+45,5,5));
        }

    }
}

//添加点，起点终点
void MainWindow::add_line(QPoint point)
{
    if(point.x()>810||point.x()<10||point.y()<45||point.y()>645)//超出范围
    {
        qDebug() << "超出画图范围";
    }
    else
    {
        points.append(point);
        if(points.size()<2)
        {
            qDebug() << "请添加终点";
        }
        else
        {
            if(type == DDA)
            {
                draw_DDA(points[0],points[1]);
            }
            else if(type == BRESENHAM)
            {
                draw_BRESENHAM(points[0],points[1]);
            }
            points.clear();

        }
    }
}

//DDA划线
void MainWindow::draw_DDA(QPoint start, QPoint end)
{
//    qDebug() << "起点终点坐标"<< start.x() << " " << start.y() <<" "<<end.x()<<" "<<end.y();
    qDebug() << "DDA算法生成直线";
    if(start.x() > end.x())//将两个点的顺序变为起始点在左侧
    {
        swap(start, end);
    }
    LINE new_line;//新建一条直线
    new_line.color = now_color;//颜色
    int x1,y1,x2,y2;
    x1 = (start.x()-10)/5;
    y1 = (start.y()-45)/5;
    x2 = (end.x()-10)/5;
    y2 = (end.y()-45)/5;
    qDebug() << "起点终点坐标"<< x1 << " " << y1 <<" "<<x2<<" "<<y2;
    int dx = x2 - x1;//计算dx
    int dy = y2 - y1;//计算dy

    //计算一共需要多少个点
    int steps = 0;
    if(abs(dx) > abs(dy))
    {
        steps = abs(dx);
    }
    else
    {
        steps = abs(dy);
    }

    //计算x，y的增量
    float inc_x = (float)dx / (float)steps;
    float inc_y = (float)dy / (float)steps;
    qDebug() << "增量" << inc_x << " " << inc_y << "数量" << steps;
    QList<QPoint> list;
    list.append(QPoint(x1,y1));
    float x = x1;
    float y = y1;
    for(int i=0; i<steps; i++)//计算各个点的坐标
    {
//        qDebug() << x << " " << y;
        x += inc_x;
        y += inc_y;
        list.append(QPoint((int)(x+0.5), (int)(y+0.5)));

    }
    new_line.point = list;//将所有点合并为一条直线
    lines.append(new_line);//将直线加入集合
    update();
}

//bresenham 生成
void MainWindow::draw_BRESENHAM(QPoint start, QPoint end)
{
    qDebug() << "BRESENHAM算法生成直线";
    if(start.x() > end.x())//将两个点的顺序变为起始点在左侧
    {
        swap(start, end);
    }
    LINE new_line;//新建一条直线
    new_line.color = now_color;//颜色
    int x1,y1,x2,y2;
    x1 = (start.x()-10)/5;
    y1 = (start.y()-45)/5;
    x2 = (end.x()-10)/5;
    y2 = (end.y()-45)/5;
    qDebug() << "起点终点坐标"<< x1 << " " << y1 <<" "<<x2<<" "<<y2;
    int dx = x2 - x1;//计算dx
    int dy = y2 - y1;//计算dy
    QList<QPoint> list;
    int add_y = dy > 0 ? 1 : -1;
    int x = x1;
    int y = y1;
    list.append(QPoint(x1,y1));
    dx = abs(dx);
    dy = abs(dy);
    if(dx > dy)//当斜率小于1时
    {
        int p = 2 * dy - dx;
        int dy2 = 2 * dy;
        int dydx2 = 2 * dy - 2 * dx;
        while(x != x2)
        {
            x += 1;
            if(p < 0)
            {
                p += dy2;
            }
            else
            {
                p += dydx2;
                y += add_y;
            }
            list.append(QPoint(x, y));
        }
    }
    else//斜率大于1时
    {
        int p = 2 * dx - dy;
        int dx2 = 2 * dx;
        int dydx2 = 2 * dx - 2 * dy;
        while(y != y2)
        {
            y += add_y;
            if(p < 0)
            {
                p += dx2;
            }
            else
            {
                x += 1;
                p += dydx2;
            }
            list.push_back(QPoint(x, y));
        }
    }
    new_line.point = list;//将所有点合并为一条直线
    lines.append(new_line);//将直线加入集合
    update();
}



